home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Resource for Source: C/C++
/
Resource for Source - C-C++.iso
/
misc_src
/
knowhow4
/
outwin.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-01
|
17KB
|
715 lines
#include <stdlib.h>
#include "outwin.h"
#include "cursor.h"
#include "global.h"
loc get_param(char* str) // Read parameter for command and
{ // convert in to number
int sh = strchr(str, ' ') - str; // f.e. in @FONT 1 .., 1 is parameter
char ch[5]; memset(ch, '\0', 5);
strncpy(ch, str, sh);
return loc(atoi(ch), sh + 1);
}
///////////////////////////
int ret_count(char* s) // counts '\n' symbols in the string
{
char* c = s;
int n;
for(n = 0; c = strchr(c, '\n'); n++)
c++;
return n;
}
/////////////////////////
OutputWindow::OutputWindow(rect coordinates, char* vName,
int b_type, int s, int bak,
int attr, int interv, int p_height)
: Window(coordinates, "", "", s, (BORDERS)b_type)
{
end = 0;
page = (char*)malloc(st_page_height * max_string_len);
start = loc(0, 0);
interval = interv;
bak_color = bak;
attr_color = attr;
curs = loc(0, interval);
viewName = strdup(vName);
page_height = p_height;
file_position = 0;
pages = (long*)malloc(num_pages * sizeof(long) + 2);
pages[0] = 1;
pages[1] = 0;
// contexts = (context*)malloc(MAXKEYS * sizeof(context)); // if another solutions does not work
// new context()[MAXKEYS]; // for BC 2.0
contexts = new context[MAXKEYS]; // for BC 3.0
key_rects = new special[MAXKEYS];
number = 0;
load_file();
}
////////////////////////
OutputWindow::~OutputWindow()
{
delete pages;
delete viewName;
delete page;
delete contexts;
delete key_rects;
}
/////////////////////////
void OutputWindow::show()
{
Window::show();
load();
view();
mouseHideCursor();
rect r = user_screen();
curs = loc(0, interval);
cursor.set_cursor(r.origin.X, r.origin.Y + interval);
cursor.show_cursor();
mouseShowCursor();
}
//////////////////////////
void OutputWindow::mouse_curs(loc ms_pos)
{
rect r = user_screen();
int x = ((ms_pos.X - r.origin.X) / pScreenSet->standart_width)
* pScreenSet->standart_width;
int y = ((ms_pos.Y - r.origin.Y) / interval + 1) * interval;
if(!r.contains(rect(x + r.origin.X, y + r.origin.Y - interval,
x + r.origin.X + pScreenSet->standart_width, y + r.origin.Y)))
return ;
curs = loc(x, y);
}
/////////////////////////
void OutputWindow::view()
{
settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
setusercharsize(1, 1, 1, 1);
settextjustify(LEFT_TEXT, TOP_TEXT);
rect r = user_screen();
setviewport(r.origin.X, r.origin.Y, r.corner.X, r.corner.Y, 1);
mouseHideCursor();
curs = loc(1, interval);
int num = ret_count(page);
if(start.Y > num)
start.Y = num;
char* str = page;
int count_ret = start.Y;
loc skip(0, 0);
setfillstyle(SOLID_FILL, bak_color);
bar(0, 0, r.width(), r.height());
char tm[max_string_len]; // max len
int flag = start.X;
int is_first = 0; // first pass - text, second - icons
number = 0;
while(1)
{
memset(tm, '\0', max_string_len);
int i = 0;
while(str[i] != '\n' && str[i] && str[i] != '@')
{ // @ - spec. symbol
tm[i] = str[i];
i++;
}
if(*tm && !count_ret && strlen(tm) > flag)
{
skip.X = (skip.X - flag > 0) ? (skip.X - flag) : 0;
int real_skip = skip.X * textwidth(" ");
curs.X += real_skip;
if(!is_first)
{
bar(curs.X, curs.Y - interval + 1,
curs.X + textwidth(tm + flag + skip.X), curs.Y);
outtextat(loc(curs.X, curs.Y - interval + 1), tm + flag + skip.X);
}
curs.X += textwidth(tm + flag + skip.X);
flag = 0; skip = loc(0, 0);
}
else flag -= strlen(tm);
if(str[i] == '\n')
{
if(curs.Y + interval <= r.height())
{
i++; curs.X = 1; flag = start.X;
if(count_ret > 0)
count_ret--;
else curs.Y += interval;
skip = loc(0, 0); // !!!
}
else
{
if(is_first)
break;
else
{
is_first = 1;
curs = loc(1, interval);
str = page;
count_ret = start.Y;
skip = loc(0, 0);
flag = start.X;
continue;
}
}
}
switch(str[i])
{
case '@':
char command[10];
memset(command, '\0', 10);
i++;
char* c = strchr(str + i, ' ');
int n = c - str - i;
strncpy(command, str + i, n);
i += n + 1;
int fl = screenXL(flag);
skip = process(str + i, command, fl, count_ret, is_first);
i += skip.Y;
break;
}
if(!str[i] || (curs.Y > r.height() + 1))
{
if(is_first)
break;
else
{
is_first = 1;
curs = loc(1, interval);
str = page;
count_ret = start.Y;
skip = loc(0, 0);
flag = start.X;
continue;
}
}
str = str + i;
}
setviewport(0, 0, getmaxx(), getmaxy(), 1);
mouseShowCursor();
}
////////////////////////////
void OutputWindow::exe(int act)
{
e.what = act ? KEYEVENT : NOEVENT;
global_i[0] = action_type;
switch(act)
{
case AC_LEFT: e.key = EVENT_LEFT; break;
case AC_RIGHT: e.key = EVENT_RIGHT; break;
case AC_UP: e.key = EVENT_UP; break;
case AC_DOWN: e.key = EVENT_DN; break;
case AC_PG_UP: e.key = EVENT_PG_UP; break;
case AC_PG_DN: e.key = EVENT_PG_DN; break;
case AC_HOME: e.key = EVENT_HOME; break;
case AC_END: e.key = EVENT_END; break;
case AC_CANCEL: e.key = (isRet(RET_REMOVE))
? EVENT_ALT_F3 : EVENT_ESC;
break;
case AC_OK: e.key = EVENT_F2; break;
case AC_PREV: e.key = EVENT_ALT_F1; break;
}
rect r = user_screen();
mouseHideCursor();
if(!act)
hilite();
mouseShowCursor();
while(1)
{
mouseShowCursor();
if(!act)
get_event();
mouseHideCursor();
if(e.what == KEYEVENT)
switch(e.key)
{
case EVENT_ALT_F1: box_move(AC_PREV); break;
case EVENT_RIGHT: box_move(AC_RIGHT); break;
case EVENT_LEFT: box_move(AC_LEFT); break;
case EVENT_UP: box_move(AC_UP); break;
case EVENT_DN: box_move(AC_DOWN); break;
case EVENT_HOME: box_move(AC_HOME); break;
case EVENT_PG_UP: box_move(AC_PG_UP); break;
case EVENT_END: box_move(AC_END); break;
case EVENT_PG_DN: box_move(AC_PG_DN); break;
case EVENT_CTRL_PG_UP: box_move(AC_CTRL_PG_UP); break;
case EVENT_ESC: global_num = 0; unhilite();
return;
case EVENT_F6:
case EVENT_F10:
case EVENT_TAB:
case EVENT_ALT_F3:
case EVENT_ALT_F4:
case EVENT_ALT_TAB:
unhilite(); global_num = 0; return;
case EVENT_F2:
case EVENT_RETURN :
if(!act)
{
box_move(AC_SELECT);
break;
}
else
{
global_i[0] = action_type;
global_num = 1;
return;
}
case EVENT_ALT_P:
// case EVENT_ALT_F:
global_i[0] = action_type;
global_num = 1;
return;
}
else
{
mouseHideCursor();
if(!mouse_in(loc(e.where()))) // outside of menu box
{
unhilite();
global_num = 0;
return;
}
cursor.hide_cursor();
mouse_curs(loc(e.where()));
cursor.set_cursor(r.origin.X + curs.X, r.origin.Y + curs.Y);
cursor.show_cursor();
mouseShowCursor();
box_move(AC_SELECT);
}
if(act)
return;
}
}
///////////////////////////
loc OutputWindow::process(char* str, char* command, int flag, int count_ret,
int is_first)
{
rect r = user_screen();
if(!strcmp(command, "COLOR"))
{
int n = strchr(str, ' ') - str;
char ch[5]; memset(ch, '\0', 5); strncpy(ch, str, n);
int bak_new = atoi(ch);
int m = strchr(str + n + 1, ' ') - str;
memset(ch, '\0', 5); strncpy(ch, str + n + 1, m);
int attr_new = atoi(ch);
if(is_first)
return loc(0, n + m);
setfillstyle(SOLID_FILL, bak_new);
setcolor(attr_new);
return loc(0, n + m);
}
if(!strcmp(command, "RESET_COL"))
{
if(is_first)
return loc(0, 0);
setfillstyle(SOLID_FILL, bak_color);
setcolor(attr_color);
return loc(0, 0);
}
if(!strcmp(command, "FONT"))
{
int n = strchr(str, ' ') - str;
char ch[5]; memset(ch, '\0', 5); strncpy(ch, str, n);
int font_new = atoi(ch);
int m = strchr(str + n + 1, ' ') - str;
memset(ch, '\0', 5); strncpy(ch, str + n + 1, m);
int size_new = atoi(ch);
if(is_first)
return loc(0, n + m);
settextstyle(font_new, HORIZ_DIR, size_new);
return loc(0, n + m);
}
if(!strcmp(command, "KEY"))
{
char ch[10];
loc w = get_param(str);
loc h = get_param(str + w.Y);
int m = 8;
memset(ch, '\0', 10); strncpy(ch, str + w.Y + h.Y + 1, m);
if(is_first || count_ret)
return loc(0, w.Y + h.Y + m + 2);
key_add(loc(w.X, h.X), ch);
return loc(0, w.Y + h.Y + m + 2);
}
if(!strcmp(command, "REVERSE"))
{
if(is_first)
return loc(0, 0);
int attr, bak;
attr = getcolor();
struct fillsettingstype fillinfo;
getfillsettings(&fillinfo);
bak = fillinfo.color;
setcolor(bak); setfillstyle(SOLID_FILL, attr);
return loc(0, 0);
}
if(!strcmp(command, "ICON")) // @ICON TYPE NUM
{
int n = strchr(str, ' ') - str;
char ch[5]; memset(ch, '\0', 5); strncpy(ch, str, n);
int icon_type = atoi(ch);
int m = strchr(str + n + 1, ' ') - str;
memset(ch, '\0', 5); strncpy(ch, str + n + 1, m);
int icon_num = atoi(ch);
if(!is_first)
return loc(0, n + m);
loc lt = loc(r.origin.X + curs.X - flag,
r.origin.Y + curs.Y - interval - count_ret * interval);
loc size = icon_size(icon_type);
Icon* icon = new Icon(textLoc(lt), icon_num, icon_type,
NO_BORDER);
imageP im = (imageP)icon->extract();
rect dest = rect(lt, lt + size - 1);
put_image_correct(im, dest);
delete im;
delete icon;
return loc(0, n + m);
}
if(!strcmp(command, "SKIP")) // spaces to skip
{
int n = strchr(str, ' ') - str;
char ch[5]; memset(ch, '\0', 5); strncpy(ch, str, n);
int skip = atoi(ch);
return loc(skip, n);
}
return loc(0, 0); // loc.X - to skip, loc.Y - size of command argument
}
/////////////////////////////
void OutputWindow::box_move(int act)
{
int sz;
loc res;
mouseHideCursor();
rect r = user_screen();
cursor.set_cursor(r.origin.X + curs.X, r.origin.Y + curs.Y);
cursor.hide_cursor();
switch(act)
{
case AC_SELECT:
int c_num = on_special();
if(c_num) // number of context + 1
{
c_num--;
listed.add(loc(pages[0], start.Y));
pages[0] = contexts[c_num].page;
file_position = pages[pages[0]];
start.Y = contexts[c_num].line;
start.X = 0;
load();
view();
curs = loc(0, interval);
}
break;
case AC_PREV:
loc prev = listed.remove();
if(prev.X == 0) break; // at the top - no more prev. pages
pages[0] = prev.X;
start.Y = prev.Y;
file_position = pages[pages[0]];
load();
view();
curs = loc(0, interval);
break;
case AC_LEFT:
sz = pScreenSet->standart_width;
if(curs.X >= sz) { curs.X -= sz; }
else if(start.X > 0)
{
res = curs;
start.X -= 1;
view();
curs = res;
}
break;
case AC_RIGHT:
sz = pScreenSet->standart_width;
if(curs.X < r.width() - interval) { curs.X += sz; }
else
{
res = curs;
start.X += 1;
view();
curs = res;
}
break;
case AC_HOME:
res.Y = curs.Y; start.X = 0; view(); curs = loc(0, res.Y); break;
case AC_END:
sz = r.width() / pScreenSet->standart_width;
start.X += sz;
res.Y = curs.Y;
view();
curs = loc(0, res.Y);
break;
case AC_UP:
sz = interval;
if(curs.Y > sz)
{
curs.Y -= sz;
break;
}
if(start.Y > 0)
{
res = curs; start.Y -= 1;
view(); curs = res;
}
else // if we must reload
{
if(pages[0] <= 1)
break;
start.Y = page_height / 2;
pages[0]--;
file_position = pages[pages[0]];
load();
res = curs;
view();
curs = res;
}
break;
case AC_PG_UP:
if(start.Y < r.height() / interval)
{
if(pages[0] <= 1)
{
if(start.Y > 0)
{
start.Y = 0;
view();
curs = loc(0, interval);
}
break;
}
start.Y += page_height / 2 - r.height() / interval;
pages[0]--;
file_position = pages[pages[0]];
load();
}
else start.Y -= r.height() / interval;
res = curs;
view(); curs = res; break;
case AC_DOWN:
sz = interval;
if(curs.Y < r.height() - interval)
{
curs.Y += sz;
break;
}
if(start.Y + r.height() / interval < page_height - 1)
{
res = curs; start.Y += 1;
view(); curs = res;
}
else
{
if(end) break;
pages[0]++;
file_position = pages[pages[0]];
start.Y = page_height / 2 - r.height() / interval - 1;
load(); res = curs;
view(); curs = res;
}
break;
case AC_PG_DN:
sz = r.height() / interval;
if(start.Y + 2 * sz >= page_height)
{
if(end) break;
start.Y -= (page_height / 2 - sz);
pages[0]++;
file_position = pages[pages[0]];
load();
}
else start.Y += sz;
res = curs; view(); curs = res;
break;
case AC_CTRL_PG_UP:
pages[0] = 1;
file_position = pages[pages[0]];
start = loc(0, 0);
load(); view();
curs = loc(0, interval);
break;
}
cursor.set_cursor(r.origin.X + curs.X, r.origin.Y + curs.Y);
cursor.show_cursor();
mouseShowCursor();
}
//////////////////////////
int OutputWindow::load()
{
memset(page, '\0', st_page_height * max_string_len);
char str[max_string_len];
FILE *fileptr;
fileptr = fopen(viewName, "r");
fseek(fileptr, pages[pages[0]], 0);
fpos_t pos;
end = 0;
int half_count = 0;
for(int i = 0; i < page_height; i++)
{
char* c;
c = fgets(str, max_string_len - 1, fileptr);
if(c[0] == '<') //context
continue;
if(!c)
{
end = 1;
break;
}
strcpy(page + strlen(page), str);
if(half_count == 0 && i >= page_height / 2)
{
fgetpos(fileptr, &pos);
pages[pages[0] + 1] = pos; // beginning of the next half of page
half_count = 1;
}
}
fgetpos(fileptr, &pos);
file_position = pos;
pages[pages[0] + 2] = pos; // end of page
fclose(fileptr);
return end;
}
//////////////////////////
void OutputWindow::load_file()
{
rect r = user_screen();
FILE *fileptr;
fileptr = fopen(viewName, "r");
fpos_t pos;
int hp = 0; int lines = 0; int page_num = 1;
char str[max_string_len]; char* c;
int max = MAXKEYS;
while(1)
{
memset(str, '\0', 10);
c = fgets(str, max_string_len - 1, fileptr);
lines++;
if(lines >= page_height / 2)
{
lines = 0;
fgetpos(fileptr, &pos);
pages[page_num + 1] = pos; // beginning of the next half of page
page_num++;
}
if(!c)
break;
if (hp == max - 1)
{
contexts = (context*)realloc(contexts, MAXKEYS * sizeof(context));
max = 0;
}
if (str[0] != '<')
continue;
strncpy(contexts[hp].cont_name, str + 1, 8);
contexts[hp].cont_name[8] = '\0';
contexts[hp].page = page_num;
if(lines < page_height - r.height() / interval)
contexts[hp].line = lines - 1;
else
contexts[hp].line = page_height - r.height() / interval;
hp++;
}
fclose(fileptr);
}
/////////////////////////////
void OutputWindow::key_add(loc wh, char* ch)
{
if(number > MAXKEYS - 1)
key_rects = (special*)realloc(key_rects, MAXKEYS * sizeof(special));
key_rects[number].ltrb = rect(curs.X, curs.Y - interval,
curs.X + wh.X * pScreenSet->standart_width,
curs.Y - interval + wh.Y * interval);
strncpy(key_rects[number].cont_name, ch, 8);
key_rects[number].cont_name[8] = '\0';
number++;
}
/////////////////////////////
int OutputWindow::on_special() // number of context
{
int n = 0;
while(!key_rects[n].ltrb.contains(curs) && n < number)
n++;
if(n == number) return 0;
int m = 0;
while(strcmp(key_rects[n].cont_name, contexts[m].cont_name))
{
if(contexts[m].cont_name[0] == '\0')
return 0;
m++;
}
return m + 1;
}
/////////////////////////////
void OutputWindow::jmp_to(char* context)
{
rect r = user_screen();
int m = 0;
while(strcmp(context, contexts[m].cont_name))
{
if(contexts[m].cont_name[0] == '\0')
return;
m++; // context number
}
if(m + 1) // number of context + 1
{
pages[0] = contexts[m].page;
file_position = pages[pages[0]];
start.Y = contexts[m].line;
start.X = 0;
}
}
////////////////////////////////////
void prev_stek::add(loc page_line)
{
if(used < previous_num - 1)
{ used++; previous[used] = page_line; }
else
{
for(int i = 0; i < previous_num - 1; i++)
previous[i] = previous[i + 1];
used = i;
previous[used] = page_line;
}
}